#ifndef RAY_TRACE_PRO_PROFILER_H
#define RAY_TRACE_PRO_PROFILER_H

#include "BBox.h"
#include "Ray.h"
#include "RayTraceSystem.h"
#include "Windows/GxThreads.h"

using namespace GxLibMath;
using namespace GxLibBasic;

namespace RayTracePro
{
	class BvhProfiler
	{
	public:
		GxWinSystem::Threading::SpinLock spinLock;
		__int64 minNodes, maxNodes, sumNodes, minLeaves, maxLeaves, sumLeaves, 
			minTri, maxTri, sumTri, minHit, maxHit, sumHit, sumBadNodes;
		float minRate, maxRate, sumRate;
		__int64 avgRateCount;
		__int64 rays;
		long long BadSplits;
		BvhProfiler()
		{
			Clear();
		}
		void Clear()
		{
			BadSplits = 0;
			minNodes = INT_MAX; maxNodes=0; sumNodes=0; minLeaves=INT_MAX; maxLeaves=0; sumLeaves=0; 
			minTri = INT_MAX; maxTri=0; sumTri=0; minHit=INT_MAX; maxHit=0; sumHit=0;
			minRate = FLT_MAX; maxRate = 0.0f; sumRate = 0.0f;
			sumBadNodes = 0;
			avgRateCount = 0;
			rays = 0;
		}
		//Array<int, true> LeavesTraversed, NodesTraversed, TrianglesTested, TrianglesHit;
		inline void AddRecord(int leavesTraversed, int nodesTraversed, int trianglesTested, int hits, int badNodes)
		{
			/*if (nodesTraversed > 200)
				printf("warning\n");*/
			spinLock.Lock();
			rays ++;
			sumNodes += nodesTraversed;
			sumLeaves += leavesTraversed;
			sumTri += trianglesTested;
			sumHit += hits;
			sumBadNodes += badNodes;
			if (nodesTraversed < minNodes)
				minNodes = nodesTraversed;
			if (nodesTraversed > maxNodes)
				maxNodes = nodesTraversed;

			if (trianglesTested < minTri)
				minTri = trianglesTested;
			if (trianglesTested > maxTri)
				maxTri = trianglesTested;

			if (leavesTraversed < minLeaves)
				minLeaves = leavesTraversed;
			if (leavesTraversed > maxLeaves)
				maxLeaves = leavesTraversed;

			if (hits < minHit)
				minHit = hits;
			if (hits > maxHit)
				maxHit = hits;

			if (trianglesTested > 0)
			{
				float rate = hits/(float)trianglesTested;
				sumRate += rate;
				if (rate < minRate)
					minRate = rate;
				if (rate > maxRate)
					maxRate = rate;
				avgRateCount++;
			}
			/*LeavesTraversed.Add(leavesTraversed);
			NodesTraversed.Add(nodesTraversed);
			TrianglesTested.Add(trianglesTested);
			TrianglesHit.Add(hits);*/
			spinLock.Unlock();
		}
	};
}

#endif